﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace MyServer.Udp
{
    /// <summary>
    /// 为Udp虚拟连接提供数据暂存
    /// </summary>
    public static class UdpDataHolder
    {
        /// <summary>
        /// 数据列表，其中键为远端终结点的字符表示，值为该为连接暂存的内存数据流
        /// </summary>
        private static SortedList HoldedData = SortedList.Synchronized(new SortedList());

        private static object LockObj = new object();

        /// <summary>
        /// 检测指定的终结点是否是新加入的连接
        /// </summary>
        /// <param name="RemotePoint"></param>
        /// <returns></returns>
        public static bool CheckIsNewConnection(string RemotePoint)
        {
            lock (LockObj)
            {
                string[] Keys = new string[HoldedData.Count];
                HoldedData.Keys.CopyTo(Keys, 0);
                foreach (string item in Keys)
                {
                    if (item == RemotePoint)
                        return false;
                }
                return true;
            }
        }

        /// <summary>
        /// 暂存指定数据
        /// </summary>
        /// <param name="RemotePoint">表示数据的远端节点</param>
        /// <param name="Data">表示从该节点接收的数据</param>
        public static void AddData(string RemotePoint, byte[] Data)
        {
            lock (LockObj)
            {
                string[] Keys = new string[HoldedData.Count];
                HoldedData.Keys.CopyTo(Keys, 0);
                MemoryStream stream = null;
                foreach (string item in Keys)
                {
                    stream = (MemoryStream)HoldedData[item];
                    if (item == RemotePoint)
                    {
                        HoldedData.Remove(item);
                        if (stream.Position >= stream.Length)
                        {
                            stream = new MemoryStream();
                            stream.Write(Data,0,Data.Length);
                            stream.Position = 0;
                        }
                        else
                        {
                            byte[] UnReadedByte = new byte[stream.Length - stream.Position];
                            stream.Read(UnReadedByte, (int)stream.Position, UnReadedByte.Length);
                            stream = new MemoryStream();
                            stream.Write(UnReadedByte, 0, UnReadedByte.Length);
                            stream.Write(Data, 0, Data.Length);
                            stream.Position = 0;
                        }
                        HoldedData.Add(item, stream);
                        return;
                    }
                    else
                    {
                        if (stream.Position >= stream.Length)
                        {
                            HoldedData.Remove(item);
                        }
                    }
                }
                stream = new MemoryStream(Data);
                HoldedData.Add(RemotePoint, stream);
            }

        }

        /// <summary>
        /// 获取暂存器中与指定远程终结点关联的流
        /// </summary>
        /// <param name="RemotePoint">远程终结点</param>
        /// <returns>获取到的内存流</returns>
        public static MemoryStream GetStream(string RemotePoint)
        {
            lock (LockObj)
            {
                string[] Keys = new string[HoldedData.Count];
                HoldedData.Keys.CopyTo(Keys, 0);
                MemoryStream stream = null;
                foreach (string item in Keys)
                {
                    stream = (MemoryStream)HoldedData[item];
                    if (item == RemotePoint)
                    {
                        return stream;
                    }
                    else
                    {
                        if (stream.Position >= stream.Length)
                        {
                            HoldedData.Remove(item);
                        }
                    }
                }
                return null;
            }
        }

        /// <summary>
        /// 获取暂存器中是否有与指定终结点关联的数据
        /// </summary>
        /// <param name="RemotePoint">关联的远程终结点</param>
        public static int CheckDataAvilable(string RemotePoint)
        {
            lock(LockObj)
            {
                string[] Keys = new string[HoldedData.Count];
                HoldedData.Keys.CopyTo(Keys, 0);
                MemoryStream stream = null;
                foreach (string item in Keys)
                {
                    stream = (MemoryStream)HoldedData[item];
                    if (item == RemotePoint)
                    {
                        return (int)(stream.Length-stream.Position);
                    }
                }
                return 0;
            }
        }

        /// <summary>
        /// 清除暂存器中暂存的指定终结点的数据
        /// </summary>
        /// <param name="RemotePoint"></param>
        /// <returns></returns>
        public static void ClearData(string RemotePoint)
        {
            lock (LockObj)
            {
                string[] Keys = new string[HoldedData.Count];
                HoldedData.Keys.CopyTo(Keys, 0);
                MemoryStream stream = null;
                foreach (string item in Keys)
                {
                    stream = (MemoryStream)HoldedData[item];
                    HoldedData.Remove(item);
                    stream.Dispose();
                }
            }
        }

    }
}
